//------------------------------------------------
// mips.v
// David_Harris@hmc.edu 3 November 2005
// Pipelined MIPS processor
//------------------------------------------------

// pipelined MIPS processor
module mips(input         clk, reset,
            output [31:0] pcF,
            input  [31:0] instrF,
            input         instrAckF,
            input         instrInvalidAddressF,
            output        memwriteM, memtoregM,
            input         dataAckM,
            input         dataInvalidAddressM,
            output [31:0] writeAddressM, writedataM,
            input  [31:0] readdataM,
            input  [15:0] interrupts,
            input   [4:0] debugAddress,
            inout  [31:0] debugData
			);

    wire [5:0]  opD, functD;
    wire [1:0]  regdstE, jumpD;
    wire        alusrcAE,  alusrcBE, 
                pcsrcD,
                memtoregE, memtoregW, regwriteE, regwriteM, regwriteW,
                notBubbleE, notBubbleM;
    wire [2:0]  compcontrolD;
    wire [3:0]  alucontrolE;
    wire        flushE, compD;
    wire [4:0]  rsD;
    wire [31:0] pcD, pcE, pcM, cp0ReadData, cp0WriteDataW;
    wire [7:0]  cp0ReadAddressM, cp0WriteAddressW;

    controller c(/* inputs */
                 /* from off chip */
                 clk, reset,
                 /* from datapath */
                 opD, functD, rsD, stallE, stallM, flushE, flushM, flushW, compD,
                 /* outputs */
                 memtoregE, memtoregM, memtoregW, cp0ToRegE, cp0ToRegW, memwriteD, memwriteM, memwriteW,
                 pcsrcD, branchD, alusrcAE, alusrcBE,
                 regdstE, regwriteD, regwriteE, regwriteM, regwriteW,
                 linkE, signextD, jumpD, compcontrolD, alucontrolE,
                 /* to coprocessor0 */
                 cp0WriteEnableW, eretM, overflowAbleM,
                 addressErrorOnLoadAbleM, addressErrorOnStoreAbleM,
                 badInstructionM
                 );
  
    datapath dp(/* inputs */
                /* from off chip */
                clk, reset,
                /* from memory */
                instrF, readdataM, instrAckF, dataAckM,
                instrInvalidAddressF,
                /* from controller */
                memtoregE, memtoregM, memtoregW, cp0ToRegE, cp0ToRegW,
                pcsrcD, branchD,
                alusrcAE, alusrcBE,
                regdstE, regwriteE, regwriteM, regwriteW,
                memwriteD, memwriteM, memwriteW,
                linkE, jumpD, compcontrolD, alucontrolE, signextD,
                /* outputs */
                /* to memory */
                pcF, 
                writeAddressM, writedataM,
                /* to controller */
                opD, functD, rsD, compD, stallE, stallM, flushE, flushM, flushW,
                /* to coprocessor0 */
                cp0ReadAddressM, cp0WriteAddressW,
                pcD, pcE, pcM, flushD,
                cp0WriteDataW, overflowM, instrInvalidAddressM,
                /* from coprocessor0 */
                cp0ReadData, cp0Jump,
                /* external to regfile, for pc debug */
                debugAddress, debugData
                );

    coprocessor0 cp0(/* inputs */
                     /* from off chip */
                     clk, reset, interrupts,
                     /* for move to/from cp0 */
                     cp0WriteAddressW, cp0WriteEnableW, cp0WriteDataW,
                     /* for keeping track */
                     writeAddressM, pcF, pcD, pcE, pcM,
                     memwriteM, dataAckM, jumpD, regwriteD, branchD, flushD, flushE, flushM,
                     eretM,
                     /* exception inputs */
                     overflowAbleM, overflowM,
                     addressErrorOnLoadAbleM, addressErrorOnStoreAbleM,
                     instrInvalidAddressM, dataInvalidAddressM, 
                     badInstructionM,
                     cp0ReadAddressM,
                     /* outputs */
                     cp0ReadData, cp0Jump
                     );

endmodule
